/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com */

/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "system.h"

namespace tri {
namespace sys {

std::string join(std::string d, std::string s) {
    if (d=="") {
        return s;
    }

    if (s=="") {
        return d;
    }
    
    if( d.c_str()[d.size()-1] == '\\' ){
    	return d+s;
    }
    return d+"\\"+s;
}

bool isFile(std::string file) {
    FILE* fh=NULL;
    fh = fopen(file.c_str(), "r");
    if (fh==NULL) {
        return false;
    }
    fclose(fh);
    return true;
}

bool isDir(std::string path) {
    DIR* pdir=NULL;
    pdir = opendir(path.c_str());
    if (pdir==NULL) {
        return false;
    }
    closedir(pdir);
    return true;
}

int getFiles(std::string path, std::vector<std::string>& v) {
    DIR* pdir=NULL;
    pdir = opendir(path.c_str());
    struct dirent *pent=NULL;
    if (pdir==NULL) {
        return -1;
    }
    v.clear();
    while (pent=readdir(pdir)) {
        if (pent==NULL) {
            return -1;
        }
        std::string s(pent->d_name);
        if (isFile(join(path, s))) {
            v.push_back(s);
        }
    }

    return 0;
}

int getFiles(std::string path, std::vector<std::string>& v,
        std::vector<std::string>& ext) {
    DIR* pdir=NULL;
    pdir = opendir(path.c_str());
    struct dirent *pent=NULL;
    if (pdir==NULL) {
        return -1;
    }
    v.clear();
    while (pent=readdir(pdir)) {
        if (pent==NULL) {
            return -1;
        }
        std::string s(pent->d_name);
        if (isFile(join(path, s))) {

            if (ext.size() == 0) {
                v.push_back(s);
            } else {
                for (unsigned int i=0; i<ext.size() ; i++) {
                    if (hasExtension(s, ext[i])) {
                        v.push_back(s);
                        break;
                    }
                }
            }
        }
    }

    return 0;
}

std::string getCWDir() {
#ifdef WIN32
    char temp[_MAX_PATH];
    getcwd(temp, _MAX_PATH);
    return std::string(temp);
#else
    char temp[FILENAME_MAX];
    getcwd(temp, FILENAME_MAX);
    return std::string(temp);
#endif
}

int getDirs(std::string path, std::vector<std::string>& v) {
    DIR* pdir=NULL;
    pdir = opendir(path.c_str());
    struct dirent *pent=NULL;
    if (pdir==NULL) {
        return -1;
    }
    v.clear();
    while (pent=readdir(pdir)) {
        if (pent==NULL) {
            return -1;
        }

        std::string s(pent->d_name);
        if (isDir(join(path, s))) {
            v.push_back(s);
        }
    }
    return 0;
}

int listDir(std::string path, std::vector<std::string>& v) {

    DIR* pdir=NULL;
    pdir = opendir(path.c_str());
    struct dirent *pent=NULL;
    if (pdir==NULL) {
        return -1;
    }
    v.clear();
    while (pent=readdir(pdir)) {
        if (pent==NULL) {
            return -1;
        }
        v.push_back(pent->d_name);
    }

    return 0;
}

bool exists(std::string path) {
    return isFile(path) || isDir(path);
}

bool hasExtension(std::string f, std::string ext) {
    if (f.size()<ext.size()) {
        return false;
    }

    bool ret = true;
    for (int i = 0; i<(int)ext.size(); i++) {
        if (ext.c_str()[ext.size()-1-i] != f.c_str()[f.size()-1-i]) {
            ret = false;
            break;
        }
    }

    return ret;
}

std::string formatPathString(std::string path){
	std::string ret = "";
	 for (int i = 0; i<(int)path.size(); i++) {
		char c = path.c_str()[i];
		if (c == '/' ){
			ret.append(1,'\\');
		}else{
			ret.append(1,c);
		}
    }
	 
	 return ret;
}

bool hasParentDirectory(std::string _path){
	std::string path = formatPathString(_path);
	std::vector<std::string> dirs;
	utils::split(dirs,path,'\\');
	if (dirs.size()> 1){
		return dirs[0] != "";
	}
	return false;
}

std::string getParentDirectory(std::string _path){
	std::string path = formatPathString(_path);
	if (hasParentDirectory(path)){
		std::vector<std::string> dirs;
		tri::utils::split(dirs,path,'\\');
		std::string ret;
		if ( dirs.size() == 2 ){
			return dirs[0];
		}else if(dirs.size() > 2){
			ret = join(dirs[0],dirs[1]);
			for (unsigned int i = 2;i<dirs.size()-1;i++){
				ret = join(ret,dirs[i]);
			}
			return ret+"\\";
		}
	}
	
	return "";
}

}
}
